<template>
  <el-cascader ref="contentRef" v-bind="$attrs" v-model="cascaderValue" :filterable="filterable" :clearable="clearable" :options="options" :props="cascaderProps"
    :show-all-levels="showAllLevels" :collapse-tags-tooltip="collapseTagsTooltip" :filter-method="filterMethod" @change="change" />
</template>
<script setup>
import useCommonStore from "@/store/modules/common";
import * as api from '@/api/public'
const config = {
  0: {
    key: 'personnel', // 人员
    value: 'user_id',
    children: 'sub'
  },
  1: {
    key: 'department', // 部门
    children: 'sub',
  },
  2: {
    key: 'classify', // 分类
    children: 'son'
  },
  3: {
    key: 'areaTree', // 国内省市区
    children: 'sub'
  },
  department: {
    key: 'department', // 部门
    children: 'sub',
    value: 'name',
    emitPath: true
  },
}


const props = defineProps({
  modelValue: { type: [Object, Array, String, Number], default: () => '' },
  type: { type: String, default: '0' },
  multiple: Boolean,
  filterable: { type: Boolean, default: true },
  clearable: { type: Boolean, default: true },
  checkStrictly: Boolean,
  showAllLevels: { type: Boolean, default: false },
  emitPath: { type: Boolean, default: false },
  level: { type: Number, default: 0 },
  collapseTagsTooltip: { type: Boolean, default: true },
});
const emit = defineEmits(['update:modelValue', 'change', 'changeEmitPath'])
const cascaderValue = computed({
  get() {
    let val = props.modelValue
    if (Array.isArray(val) && props.type === 'department') {
      val = (val || []).map(d => d.split('/'))
    }
    return val
  },
  set(val) {
    if (Array.isArray(val) && props.type === 'department') {
      val = (val || []).map(d => d.join('/'))
    }
    emit('update:modelValue', val)
  }
})
const commonStore = useCommonStore();
const item = config[props.type]
const { key } = item

// 指定层级
const { level } = props
const child = item.children
function clearArrayLevels(arr, level) {
  if (level <= 0) return []
  if (!Array.isArray(arr)) {
    return arr;
  }

  return arr.map(item => {
    if (Array.isArray(item[child])) {
      item[child] = clearArrayLevels(item[child], level - 1);
    }
    return item;
  })
}

const keyName = level ? key + (level || '') : key
if (!commonStore.options[keyName] && !item.lazy) {
  try {
    api[key]().then(data => {
      let opts = []
      if (level) {
        opts = clearArrayLevels(data, level)
      } else {
        opts = data
      }
      commonStore.setOptions(keyName, opts)
    })
  } catch (error) {
    console.log('error', error)
  }
}

const options = computed(() => item.lazy ? [] : commonStore.options[keyName])

const cascaderProps = computed(() => {
  const { lazy, lazyLoad, label = 'name', value = 'id', children = 'sub' } = item
  if (item.lazy) return { lazy, lazyLoad }
  return {
    emitPath: item.emitPath || props.emitPath,
    checkStrictly: props.checkStrictly,
    multiple: props.multiple,
    label,
    value,
    children,
  }
})

const filterMethod = (node, val) => {
  if (!!~node.text.indexOf(val) || !!~node.text.toUpperCase().indexOf(val.toUpperCase())) {
    return true
  }
}

const contentRef = ref()
const change = (value) => {
  const getCheckedNodes = contentRef?.value.getCheckedNodes()
  const labels = props.emitPath ? (getCheckedNodes[0]?.pathLabels || []) : props.multiple ? getCheckedNodes.map(d => d.label) : getCheckedNodes[0]?.label
  emit('change', { value, labels })
  if(!props?.emitPath) return
  changeEmitPath(value)
}

const getLabelByValuePath = (nodes, valuePath) => {
  let labels = [];
  let currentNodes = nodes;
  for (const value of valuePath) {
    const target = currentNodes.find(node => node.id === value);
    if (target) {
      labels.push(target.name);
      currentNodes = target.son || [];
    } else {
      break;
    }
  }
  return labels;
};

const changeEmitPath = (value) => {
  const labels = value.map(valuePath => getLabelByValuePath(options.value, valuePath));
  emit('changeEmitPath', { value, labels })
}
defineExpose({ contentRef })
</script>